package com.example.demo.aspectJ;

import com.example.demo.annotation.MyLog;
import com.google.common.collect.Maps;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Map;

/**
 * 软件著作权:王艳明
 * 系统名称:SpringBoot后台管理系统
 *
 * @author WangYanming
 * @ClassName 类:MyLogAspectJ.java
 * @Description 功能描述:日志切面类
 * @Version 1.0
 * @date 2025-09-24 下午 06:10
 */
@Aspect
@Component
public class MyLogAspectJ {


    /**
     * 定义切点，拦截所有带有@Log注解的方法
     */
    @Pointcut("@annotation(com.example.demo.annotation.MyLog)")
    public void logPointCut() {
    }

    /**
     * 后置通知，在方法执行后记录日志
     */
    @AfterReturning(pointcut = "logPointCut()", returning = "jsonResult")
    public void saveOperationLog(JoinPoint joinPoint, Object jsonResult) {
        // 创建日志对象
        Map<String, String> log = Maps.newHashMap();

        // 获取当前用户
        String username = getCurrentUsername();
        log.put("username", username);

        // 获取操作内容（从注解中获取）
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        MyLog operationLog = method.getAnnotation(MyLog.class);
        if (operationLog != null) {
            log.put("operationContent", operationLog.value());
        }

        // 获取请求信息
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes != null) {
            HttpServletRequest request = attributes.getRequest();
            // 获取IP地址
            log.put("ipAddress", getIpAddress(request));
        }

        // 记录调用方法和参数
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = signature.getName();
        log.put("method", className + "." + methodName);
        // 请求参数
        log.put("params", Arrays.toString(joinPoint.getArgs()));
        // 返回结果
        log.put("result", jsonResult.toString());

        // 保存日志
        System.out.println(log.toString());
    }

    /**
     * 获取当前登录用户名
     */
    private String getCurrentUsername() {
        try {
            // 这里假设使用Spring Security进行身份认证
            /*
            Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            if (principal instanceof UserDetails) {
                return ((UserDetails) principal).getUsername();
            }
            return principal.toString();
            */
            return "admin";
        } catch (Exception e) {
            return "未知用户";
        }
    }

    /**
     * 获取IP地址
     */
    private String getIpAddress(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
}
